"use client";

import React, { Fragment, useMemo, useState } from "react";
import { useRouter } from "next/navigation";
import WorkflowMenu from "./workflow-menu";
import { KeepLoader } from "@/shared/ui";
import { Trigger, Workflow } from "@/shared/api/workflows";
import {
  Button,
  Card,
  Icon,
  ListItem,
  List,
  Badge,
  Title,
} from "@tremor/react";
import { CheckCircleIcon } from "@heroicons/react/24/outline";
import { formatDistanceToNowStrict } from "date-fns";
import TimeAgo, { Formatter, Suffix, Unit } from "react-timeago";
import WorkflowGraph from "./workflow-graph";
import Modal from "@/components/ui/Modal";
import { useWorkflowRun } from "@/features/workflows/manual-run-workflow/model/useWorkflowRun";
import { useWorkflowActions } from "@/entities/workflows/model/useWorkflowActions";
import { useToggleWorkflow } from "@/features/workflows/enable-disable/model";
import { WorkflowTriggerBadge } from "@/entities/workflows/ui/WorkflowTriggerBadge";
import Link from "next/link";
import { WorkflowPermissionsBadge } from "@/entities/workflows/ui/WorkflowPermissionsBadge";
import { parseWorkflowYamlToJSON } from "@/entities/workflows/lib/yaml-utils";
import { useWorkflowZodSchema } from "@/entities/workflows/lib/useWorkflowZodSchema";
import "./workflow-tile.css";

function TriggerTile({ trigger }: { trigger: Trigger }) {
  return (
    <ListItem>
      <WorkflowTriggerBadge trigger={trigger} />
      {trigger.type === "manual" && (
        <span>
          <Icon icon={CheckCircleIcon} color="green" className="p-0" />
        </span>
      )}
      {trigger.type === "interval" && <span>{trigger.value} seconds</span>}
      {trigger.type === "alert" && (
        <span className="text-sm text-right">
          {trigger.cel && <Fragment>CEL = {trigger.cel}</Fragment>}
          {trigger.filters &&
            trigger.filters.map((filter) => (
              <Fragment key={filter.key}>
                {filter.key} = {filter.value}
              </Fragment>
            ))}
        </span>
      )}
    </ListItem>
  );
}

function WorkflowTile({ workflow }: { workflow: Workflow }) {
  // Create a set to keep track of unique providers
  const router = useRouter();

  const [openTriggerModal, setOpenTriggerModal] = useState<boolean>(false);
  const { toggleWorkflow } = useToggleWorkflow(workflow.id);

  const { deleteWorkflow } = useWorkflowActions();
  const { data: workflowYamlJSON, error: workflowParseError } = useMemo(() => {
    return parseWorkflowYamlToJSON(workflow.workflow_raw);
  }, [workflow.workflow_raw]);

  // TODO: parse permissions on backend
  const permissions = useMemo(
    () => workflowYamlJSON?.workflow?.permissions,
    [workflowYamlJSON]
  );

  const { isRunning, handleRunClick, isRunButtonDisabled, message } =
    useWorkflowRun(workflow!);

  const handleDeleteClick = async () => {
    deleteWorkflow(workflow.id);
  };

  // todo: move to a shared func/component
  const handleDownloadClick = async () => {
    try {
      // Use the raw workflow data directly, as it is already in YAML format
      const workflowYAML = workflow.workflow_raw;

      // Create a Blob object representing the data as a YAML file
      const blob = new Blob([workflowYAML], { type: "text/yaml" });

      // Create an anchor element with a URL object created from the Blob
      const url = window.URL.createObjectURL(blob);

      // Create a "hidden" anchor tag with the download attribute and click it
      const a = document.createElement("a");
      a.style.display = "none";
      a.href = url;
      a.download = `${workflow.workflow_raw_id}.yaml`; // The file will be named after the workflow's id
      document.body.appendChild(a);
      a.click();

      // Release the object URL to free up resources
      window.URL.revokeObjectURL(url);
    } catch (error) {
      console.error("An error occurred while downloading the YAML", error);
    }
  };

  const handleViewClick = async () => {
    router.push(`/workflows/${workflow.id}`);
  };

  const handleBuilderClick = async () => {
    router.push(`/workflows/builder/${workflow.id}`);
  };

  const lastExecutions = workflow?.last_executions?.slice(0, 15) || [];
  const lastProviderConfigRequiredExec = lastExecutions.filter(
    (execution) => execution?.status === "providers_not_configured"
  );
  const isAllExecutionProvidersConfigured =
    lastProviderConfigRequiredExec.length === lastExecutions.length;

  const customFormatter: Formatter = (
    value: number,
    unit: Unit,
    suffix: Suffix
  ) => {
    if (!workflow.last_execution_started && isAllExecutionProvidersConfigured) {
      return "";
    }

    const formattedString = formatDistanceToNowStrict(
      new Date(workflow.last_execution_started + "Z"),
      { addSuffix: true }
    );

    return formattedString
      .replace("about ", "")
      .replace("minute", "min")
      .replace("second", "sec")
      .replace("hour", "hr");
  };

  const zodSchema = useWorkflowZodSchema();
  const validationResult = useMemo(
    () => parseWorkflowYamlToJSON(workflow.workflow_raw, zodSchema),
    [zodSchema, workflow.workflow_raw]
  );

  function renderValidationBadge() {
    if (validationResult.success) {
      return (
        <Badge color="green" size="xs">
          Valid YAML
        </Badge>
      );
    }
    return (
      <Badge
        color="yellow"
        size="xs"
        tooltip={validationResult.error.issues
          .map((issue) => `${issue.path}: ${issue.message}`)
          .join("\n")}
      >
        {validationResult.error.issues.length} issue
        {validationResult.error.issues.length > 1 ? "s" : ""}
      </Badge>
    );
  }

  return (
    <>
      {/* TODO: fix stuck loader */}
      {isRunning && (
        <div className="fixed inset-0 z-50 flex items-center justify-center bg-black bg-opacity-50">
          <KeepLoader />
        </div>
      )}
      <Card
        className="relative flex flex-col justify-between p-4 h-full border-2 border-transparent hover:border-orange-400 overflow-hidden cursor-pointer"
        data-testid={`workflow-tile-${workflow.id}`}
      >
        <Link
          href={`/workflows/${workflow.id}`}
          aria-label={`View details for workflow: ${
            workflow?.name || "Unknown"
          }`}
        >
          <div className="absolute top-0 right-0 mt-2 mr-2 mb-2 flex items-center flex-wrap">
            {workflow.provisioned && (
              <Badge color="orange" size="xs" className="mr-2 mb-2">
                Provisioned
              </Badge>
            )}
            {workflow.alertRule && (
              <Badge color="orange" size="xs" className="mr-2 mb-2">
                Alert Rule
              </Badge>
            )}
            {workflow.disabled && (
              <Badge color="slate" size="xs" className="mr-2 mb-2">
                Disabled
              </Badge>
            )}
          </div>
          <WorkflowGraph size="sm" workflow={workflow} />
          <div className="container flex flex-col space-between">
            <div className="h-28 flex flex-col pt-2">
              <div className="flex flex-col">
                {renderValidationBadge()}
                <h2 className="truncate leading-6 font-bold text-base lg:text-lg">
                  {workflow?.name || "Unknown"}
                </h2>
              </div>
              <p className="text-gray-500 line-clamp-2 text-sm">
                {workflow?.description || "no description"}
              </p>
            </div>
            <div className="flex justify-between items-end">
              <div className="flex flex-row items-center gap-1 flex-wrap text-sm">
                {workflow.triggers.map((trigger) => (
                  <WorkflowTriggerBadge
                    key={trigger.type}
                    trigger={trigger}
                    onClick={(e) => {
                      e.stopPropagation();
                      e.preventDefault();
                      setOpenTriggerModal(true);
                    }}
                  />
                ))}
              </div>
              {permissions && (
                <div className="flex flex-row items-center gap-1 flex-wrap text-sm ml-1">
                  <WorkflowPermissionsBadge permissions={permissions} />
                </div>
              )}
              {!isAllExecutionProvidersConfigured &&
                workflow?.last_execution_started && (
                  <div className="text-gray-500 text-sm text-right cursor-pointer truncate max-w-full mt-2 grow min-w-[max-content]">
                    <TimeAgo
                      date={workflow?.last_execution_started + "Z"}
                      formatter={customFormatter}
                    />
                  </div>
                )}
            </div>
          </div>
        </Link>
        <div className="absolute top-4 right-4">
          <WorkflowMenu
            onDelete={handleDeleteClick}
            onRun={handleRunClick}
            onDownload={handleDownloadClick}
            onView={handleViewClick}
            onBuilder={handleBuilderClick}
            onToggleState={toggleWorkflow}
            isDisabled={workflow.disabled}
            runButtonToolTip={message}
            isRunButtonDisabled={!!isRunButtonDisabled}
            provisioned={workflow.provisioned}
          />
        </div>
      </Card>

      <Modal
        isOpen={openTriggerModal}
        onClose={() => {
          setOpenTriggerModal(false);
        }}
      >
        <Title>Triggers</Title>
        <div>
          {workflow.triggers.length > 0 ? (
            <List>
              {workflow.triggers.map((trigger, index) => (
                <TriggerTile key={index} trigger={trigger} />
              ))}
            </List>
          ) : (
            <p className="text-xs text-center mx-4 mt-5 text-tremor-content dark:text-dark-tremor-content">
              This workflow does not have any triggers.
            </p>
          )}
        </div>
        <div className="mt-2.5">
          <Button
            color="orange"
            size="xs"
            variant="secondary"
            onClick={() => setOpenTriggerModal(false)}
          >
            Close
          </Button>
        </div>
      </Modal>
    </>
  );
}

export default WorkflowTile;
